if (typeof String.prototype.startsWith != 'function') {
	String.prototype.startsWith = function (str){
		return this.indexOf(str) == 0;
	};
}
if (typeof String.prototype.trim != 'function') {
	String.prototype.trim = function () {
		return this.replace(/^\s*/, "").replace(/\s*$/, "");
	}
}

if (typeof String.prototype.url2link != 'function') {
	String.prototype.url2link = function() {
		var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
	    return this.replace(exp,"<a href='$1' target='_blank'>$1</a>"); 
	}
}
	

function empty(val) {
	return val == null || val == '';
}

function callEx(path, callback, errorCallback) {
	$.ajax({
		type : 'get',
		url : path,
		data : 'callback=?',
		dataType : 'jsonp',
		success : function(data) {
			if(callback) {
				callback(data);
			} else {
				alert(JSON.stringify(data));
			}
		},
		error : function(xhr, ajaxOptions, thrownError) {
			if(errorCallback) {
				errorCallback(xhr, ajaxOptions, thrownError);
			} else {
				if(xhr.status == 0) {
				} else {
					alert(xhr.status + '\n' + thrownError);
				}
			}
		}
	});
}

function ajaxErrorMessage(emsg) {
	if (emsg.substr(0,5) == '$sil$') {	/* silent mode */
		return;
	} else {
		return emsg;
	}
}

function call(path, successCallback, failCallback, errorCallback) {
	$.ajax({
		type : 'get',
		url : path,
		data : 'callback=?',
		dataType : 'jsonp',
		success : function(data) {
			if(data.result) {
				if(successCallback) {
					successCallback(data);
				}
			} else {
				if(failCallback) {
					failCallback(data);
				}
			}
		},
		error : function(xhr, ajaxOptions, thrownError) {
			if(errorCallback) {
				errorCallback(xhr, ajaxOptions, thrownError);
			} else {
				if(xhr.status == 0) {
				} else {
					alert(xhr.status + '\n' + thrownError);
				}
			}
		}
	});
}
